package com.yeban.javase.day18.test.test1;

import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Desc TODO
 * @Author yeban
 * @Date 2025/11/2
 *
 * 需求：
 * 线程1要执行打印：A和C，线程2要执行打印：B，
 * 但线程1在打印A后，要线程2打印B之后才能打印C，
 * 所以：线程1在打印A后，必须等待线程2打印完B之后才能继续执行。
 *
 * 多线程的情况下 C -> B -> A
 * 阻塞队列PriorityBlockingQueue
 *
 */
public class PriorityBlockingQueueCBA {

    public static void main(String[] args) {

        // 1.创建自定义线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1, 3,
                60L, TimeUnit.SECONDS,
                new PriorityBlockingQueue<>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        // 2.执行具备不同优先级的任务
        pool.execute(new MyRunnablepCBA(3,"任务C"));
        pool.execute(new MyRunnablepCBA(2,"任务B"));
        pool.execute(new MyRunnablepCBA(1,"任务A"));

        // 3.关闭线程池
        pool.shutdown();
    }
}

class MyRunnablepCBA implements Runnable, Comparable<MyRunnablepCBA> {
    // 优先级，数字越大优先级越高
    private int ordered;
    // 设置任务的名字
    private String name;

    public MyRunnablepCBA() {
    }

    public MyRunnablepCBA(int ordered, String name) {
        this.ordered = ordered;
        this.name = name;
    }

    // 根据ordered任务优先级，比较任务的大小
    @Override
    public int compareTo(MyRunnablepCBA o) {
        return o.ordered - this.ordered;
    }

    @Override
    public void run() {
        // 模拟任务耗时
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + " ,执行的任务是:" + name);
    }

    /**
     * 获取
     * @return ordered
     */
    public int getOrdered() {
        return ordered;
    }

    /**
     * 设置
     * @param ordered
     */
    public void setOrdered(int ordered) {
        this.ordered = ordered;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return "MyRunnablepCBA{ordered = " + ordered + ", name = " + name + "}";
    }
}
